home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / maximus / mxms_161.zip / QWKSPT.C < prev    next >
C/C++ Source or Header  |  1991-07-27  |  36KB  |  994 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*    Qwkspt.c    :QWK format routines for MaxMail                          */
  4. /*                                                                          */
  5. /****************************************************************************/
  6.  
  7. #include "MaxMail.h"
  8.  
  9. /* Some QWK specifics */
  10.  
  11. struct QWKmsghd {        /* Messages.dat header */
  12.    char  Msgstat;            /* message status byte */
  13.    char  Msgnum[7];          /* message number in ascii */
  14.    char  Msgdate[8];         /* date in ascii */
  15.    char  Msgtime[5];         /* time in ascii */
  16.    char  Msgto[25];          /* Person addressed to */
  17.    char  Msgfrom[25];        /* Person who wrote message */
  18.    char  Msgsubj[25];        /* Subject of message */
  19.    char  Msgpass[12];        /* password */
  20.    char  Msgrply[8];         /* message # this refers to */
  21.    char  Msgrecs[6];           /* # of 128 byte recs in message,inc header */
  22.    char  Msglive;            /* always 0xe1 */
  23.    char  Msgarealo;         /* area number, low byte */
  24.    char  Msgareahi;         /* area number, hi byte */
  25.    char  Msgfiller[3];        /* fill out to 128 bytes */
  26. };
  27.  
  28. union Converter {
  29.    unsigned char  uc[10];
  30.    unsigned int   ui[5];
  31.    unsigned long  ul[2];
  32.    float           f[2];
  33.    double          d[1];
  34. };
  35.  
  36. struct repmsg {
  37.    int count;
  38.    int areano;
  39.    word flags;
  40.    struct repmsg _far *next;
  41. };
  42.  
  43. #define RP_CMDFLAG  0x0001
  44.  
  45. static int Indx;        /* Message NDX file */
  46. static int PIndx;        /* Personal NDX file */
  47. static int upmsgs;
  48. static int repfile;
  49. static int msgrecs;
  50. static int confreqs;
  51. static word lastarea;
  52.  
  53. static struct repmsg _far *RP1;
  54. static struct repmsg _far *rp;
  55. static struct repmsg _far *RPprev;
  56.  
  57. static FILE *MsgFile; /* Messages.dat file */
  58. static TotRecs;
  59. extern char msg_line[];
  60. static int Aindex;
  61. static struct _aidx IDX;
  62.  
  63. static char *monthstr[] =  {  {"Jan"},{"Feb"},{"Mar"},{"Apr"},
  64.                             {"May"},{"Jun"},{"Jul"},{"Aug"},
  65.                             {"Sep"},{"Oct"},{"Nov"},{"Dec"}
  66.                          };                         
  67.  
  68.  
  69. static struct QWKmsghd *QMsgHead;
  70. extern struct _msg   amsg;
  71.  
  72. extern char _far  *msgbuffer;
  73. extern int fido_init;
  74. extern int HaveUpl;
  75.  
  76. /* Create the control.dat file for QWK packets, this only called
  77.    once per session. It also does some other initialization for
  78.    QWK handling.. */
  79.  
  80. void _pascal qwkinit(void)
  81. {
  82.    static First = TRUE;
  83.    struct find_t fbuf;
  84.  
  85.    if (First) {        /* Do this only once */
  86.       Indx = -1;
  87.       PIndx = -1;
  88.       if (!fido_init)
  89.          fidomsg_init();
  90.  
  91.       if (tdir[0])
  92.          switch_dir(tdir);        /* Switch to temp dir */
  93.  
  94.       sprintf(QWKDir,"QWK%04x",Task);
  95.       if(mkdir(QWKDir) != 0) {
  96.          if(chdir(QWKDir) != 0)
  97.             QWKDir[0] = 0;
  98.          else {        /* We are in QWKDir, let's cleanup */
  99.             if (!_dos_findfirst("*.*",_A_NORMAL,&fbuf)) {    /* Kill everything */
  100.                unlink(fbuf.name);
  101.                while (!_dos_findnext(&fbuf)) 
  102.                   unlink(fbuf.name);
  103.             }
  104.             chdir("..");        /* Restore back to parent */
  105.          }
  106.       }
  107.  
  108.       if (tdir[0])
  109.          switch_dir(PRM(sys_path));
  110.  
  111.       First = FALSE;
  112.    }
  113.    lastarea = 0xffff;
  114. }
  115.  
  116.  
  117. int _pascal openqwk(void)
  118. {
  119.    int code=0;
  120.    int x,keys,totals;
  121.    char *p;
  122.    FILE *datfile;
  123.    time_t     aclock;
  124.    struct tm  *newtime;
  125.    char fname[_MAX_FNAME];
  126.    char fext[_MAX_EXT];
  127.  
  128.  
  129.    QMsgHead = (struct QWKmsghd *) malloc(sizeof(struct QWKmsghd));
  130.    if (QMsgHead == NULL)
  131.       return 1;
  132.  
  133. /* Fill out some defaults in the Messages.dat file header */
  134.    memset(QMsgHead->Msgpass,' ',12);
  135.    memset(QMsgHead->Msgfiller,' ',3);
  136.    QMsgHead->Msglive = 0xe1;
  137.  
  138.    tempdir();
  139.    datfile = _fsopen("Control.dat","wt",SH_DENYRW);
  140.    if (datfile != NULL) {
  141.       setcolor(TextAttr[HILITE_TEXT]);
  142.       strout("\r\nCreating the Control.Dat file for your QWK packet...\r\n");
  143.       totals = 0;
  144.       strcpy(temp,PRM(system_name));
  145.       p = strtok(temp," \r\n");
  146.       fputs(p,datfile);        /* Line #1 */
  147.       fputs("\n",datfile);
  148.       fputs("               \n",datfile);
  149.       fputs(BBSphone,datfile);
  150.       fputs("\n",datfile);
  151.       fputs(PRM(sysop),datfile);
  152.       fputs("\n",datfile);
  153.       if (!BBSid[0]) {
  154.          strncpy(BBSid,PRM(system_name),8);
  155.          BBSid[8] = 0;
  156.       }
  157.       sprintf(temp,"00000,%s\n",BBSid);        /* Line #5 */
  158.       fputs(temp,datfile);
  159.       sprintf(temp,"%s.qwk",BBSid);
  160.       unlink(temp);
  161.       time(&aclock);
  162.       newtime = localtime(&aclock);
  163.       sprintf(temp,"%02d-%02d-19%02d,%02d:%02d:%02d\n",
  164.          newtime->tm_mon+1,newtime->tm_mday,newtime->tm_year,
  165.          newtime->tm_hour,newtime->tm_min,newtime->tm_sec);
  166.       fputs(temp,datfile);        /* Line #6 */
  167.       fputs(strupr(USERCFG.name),datfile);
  168.       fputs("\n",datfile);
  169.       fputs(" \n",datfile);        /* Line #8 */
  170.       fputs("0\n",datfile);
  171.       fputs("0\n",datfile);        /* Line #10 */
  172.       Aindex = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  173.       if (Aindex == -1)
  174.          aborterror(FILEOPEN,"Error opening Area index file");
  175.       for (x=0; x < 1000; x++) {    /* Display the first 1000 msg areas */
  176.          if((read(Aindex,(char *)&IDX,sizeof(struct _aidx))) != sizeof(struct _aidx))
  177.             break;
  178.          fseek(afile,IDX.offset,SEEK_SET);
  179.          fread(&AREA,astrlen,1,afile);
  180.          keys = testlock();
  181.          if (!isskiparea(x)) {
  182.             if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys) {
  183.                if(check_barareas(&AREA,-1)) 
  184.                   totals++;
  185.             }
  186.          }
  187.       }
  188.       sprintf(temp,"%d\n",totals-1);
  189.       fputs(temp,datfile);
  190.       lseek(Aindex,0L,SEEK_SET);        /* Rewind again */
  191.       for (x=0; x < 1000; x++) {    /* Display the first 1000 msg areas */
  192.          if((read(Aindex,(char *)&IDX,sizeof(struct _aidx))) != sizeof(struct _aidx))
  193.             break;
  194.          fseek(afile,IDX.offset,SEEK_SET);
  195.          fread(&AREA,astrlen,1,afile);
  196.          keys = testlock();
  197.          if (!isskiparea(x)) {
  198.             if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys) {
  199.                if(check_barareas(&AREA,-1)) {
  200.                   sprintf(temp,"%d\n",x);
  201.                   fputs(temp,datfile);
  202.                   memset(temp,0,11);
  203.                   strncpy(temp,AREA.msginfo,10);
  204.                   fputs(temp,datfile);
  205.                   fputs("\n",datfile);
  206.                }
  207.             }
  208.          }
  209.       }
  210.       close(Aindex);
  211.  
  212.       if (QWKWelcome[0]) {
  213.          _splitpath(QWKWelcome,temp,temp,fname,fext);
  214.          sprintf(temp,"%s%s\n",fname,fext);
  215.          fputs(temp,datfile);        /* This is QWK welcome file */
  216.       }
  217.       else fputs("WELCOME\n",datfile);        /* This is QWK welcome file */
  218.  
  219.       if (QWKnews[0]) {
  220.          _splitpath(QWKnews,temp,temp,fname,fext);
  221.          sprintf(temp,"%s%s\n",fname,fext);
  222.          fputs(temp,datfile);        /* This is QWK news file */
  223.       }
  224.       else fputs("WELCOME\n",datfile);        /* This is QWK news file */
  225.  
  226.       if (QWKbye[0]) {
  227.          _splitpath(QWKbye,temp,temp,fname,fext);
  228.          sprintf(temp,"%s%s\n",fname,fext);
  229.          fputs(temp,datfile);        /* This is QWK bye file */
  230.       }
  231.       else fputs("GOODBYE\n",datfile);        /* This is QWK bye file */
  232.  
  233.       fclose(datfile);
  234.       datfile = _fsopen("DOOR.ID","wt",SH_DENYRW);
  235.       if (datfile != NULL) {
  236.          sprintf(temp,"DOOR = MaxMail   \n");
  237.          fputs(temp,datfile);        /* Line #1 */
  238.  
  239.          sprintf(temp,"VERSION = %2.2f  \n",Version);
  240.          fputs(temp,datfile);        /* Line #2 */
  241.  
  242.          sprintf(temp,"SYSTEM = Maximus   \n");
  243.          fputs(temp,datfile);        /* Line #3 */
  244.  
  245.          sprintf(temp,"CONTROLNAME = MAXMAIL\n");
  246.          fputs(temp,datfile);        /* Line #4 */
  247.  
  248.          sprintf(temp,"CONTROLTYPE = ADD\n");
  249.          fputs(temp,datfile);        /* Line #5 */
  250.  
  251.          sprintf(temp,"CONTROLTYPE = DROP\n");
  252.          fputs(temp,datfile);        /* Line #6 */
  253.          sprintf(temp,"CONTROLTYPE = REQUEST\n");
  254.          fputs(temp,datfile);        /* Line #6 */
  255.          fclose(datfile);
  256.       }
  257.  
  258.       MsgFile = _fsopen("Messages.dat","wb",SH_DENYNO);
  259.       if (MsgFile != NULL) {        /* Write out the header */
  260.          fwrite("Produced by Qmail...",20,1,MsgFile);
  261.          fwrite("Copywright (c) 1987 by Sparkware.  ",35,1,MsgFile);
  262.          fwrite("All Rights Reserved",19,1,MsgFile);
  263.          for (x=0; x < 54; x++)
  264.             fwrite(" ",1,1,MsgFile);        /* Fill out rest of 128 byte record */
  265.       }
  266.       else code = 1;
  267.    }
  268.    else code = 1;
  269.  
  270.    homedir();
  271.  
  272.    TotRecs = 1;
  273.    return code;
  274. }
  275.  
  276. /* This function is called whenever a new message
  277.    area to scan is started */
  278. void _pascal qwk_newarea(struct msgupd_st *msgupd)
  279. {
  280.  
  281.    char tname[10];
  282.    if (Indx != -1)
  283.       close(Indx);
  284.  
  285.    tempdir();
  286.    sprintf(tname,"%03d.ndx",msgupd->areano);
  287.    Indx = sopen(tname,O_CREAT | O_TRUNC | O_BINARY | O_RDWR,SH_DENYRW,S_IWRITE);
  288.    homedir();
  289. }
  290.  
  291. /* This function is called whenever a new message
  292.     needs to be imported to QWK */
  293. int _pascal qwk_fidomsg(int i,int flags,struct msgupd_st *msgupd,struct msghead *MSGHD)
  294. {
  295.    char        c;
  296.    int         j,n,recs,start,origin;
  297.    int         newline,IsOurs = FALSE;
  298.    struct      find_t c_file;
  299.    long          size,filepos;
  300.    float       in,out;
  301.  
  302.    j = n = 0;
  303.    sprintf(temp1,"%s%u%s",msgupd->msgpath,i,".MSG");
  304.    if (_dos_findfirst(temp1,0,&c_file) !=0) 
  305.       return(FILE_SRCH_ERR);
  306.  
  307.    if (c_file.size >= (long) MAXFMSGSIZ)         /* Message is too big! */
  308.       return(FILE_SIZE_ERR);
  309.  
  310.    size=c_file.size - ((long) sizeof(struct _msg));
  311.    recs=sopen(temp1,O_RDONLY|O_BINARY,SH_DENYNO,S_IREAD);
  312.    if (recs < 0) 
  313.       return(FILE_OPEN_ERR);
  314.  
  315.    j = read(recs,(char *) &amsg,sizeof(struct _msg));
  316.    if (j != sizeof(struct _msg)) 
  317.       return(FILE_READ_ERR);
  318.  
  319.    _dos_read(recs,msgbuffer,(unsigned)size,&j);
  320.    if (j != (int)size) 
  321.       return(FILE_READ_ERR);
  322.  
  323.    close(recs);        /* Close the fido message */
  324.  
  325.  
  326.    if (strcmpi(amsg.to,MSGHD->ourname) == 0) {
  327.       IsOurs = TRUE;
  328.       MSGHD->ourmail++;
  329.       if (PIndx == -1) {        /* Start the Personal Index file */
  330.          tempdir();
  331.          PIndx = sopen("Personal.ndx",O_CREAT | O_TRUNC | O_BINARY | O_RDWR,SH_DENYRW,S_IWRITE);
  332.          homedir();
  333.        }
  334.    }
  335.    else {        /* Not ours */
  336.       if ((flags & PRIVATE) && (amsg.attr & MSGPRIVATE)) 
  337.          return(PVTMSG_ERR);        /* No messages to read */
  338.       IsOurs = FALSE;
  339.    }
  340.  
  341.    if (recs >= 0) {        /* We had a valid MSG file, here's the main stuff */
  342.       if (lastarea != msgupd->areano) {        /* A new area */
  343.          qwk_newarea(msgupd);
  344.          lastarea = msgupd->areano;
  345.       }
  346.       recs = 1;        /* Becomes # of 128 byte records */
  347.       TotRecs++;
  348. /* First write out the index position */
  349.       sprintf(msg_line,"%u",TotRecs);    /* Stringized version of current position */
  350.       in = (float) atof(msg_line);
  351.       out = IEEToMSBIN(in);
  352.       write(Indx,&out,sizeof(float));
  353.  
  354.  
  355.       c = 0;
  356.       write(Indx,&c,sizeof(char));        /* Conference # */
  357.  
  358.       if (IsOurs && PIndx != -1)    {    /* Set up PERSONAL area */
  359.          write(PIndx,&out,sizeof(float));
  360.          write(PIndx,&c,sizeof(char));        /* Conference # */
  361.       }
  362.  
  363. /* Now build the messages.dat msg header */
  364.       if (amsg.attr & MSGPRIVATE)
  365.          QMsgHead->Msgstat = '*';
  366.       else {
  367.          if (!(msgupd->attribute & ECHOMAIL)) {        /* Local area */
  368.             if ((amsg.attr & MSGREAD) && IsOurs)
  369.                QMsgHead->Msgstat = '-';
  370.             else QMsgHead->Msgstat = ' ';
  371.          }
  372.          else QMsgHead->Msgstat = ' ';
  373.       }
  374.       sprintf(msg_line,"%d",i);
  375.       ljstring(QMsgHead->Msgnum,msg_line,7);
  376.       sprintf(msg_line,"%02d-%02d-%02d",amsg.date_written.date.mo,amsg.date_written.date.da,
  377.          amsg.date_written.date.yr+80);
  378.       memcpy(QMsgHead->Msgdate,msg_line,8);
  379.       sprintf(msg_line,"%02d:%02d",amsg.date_written.time.hh,amsg.date_written.time.mm);
  380.       memcpy(QMsgHead->Msgtime,msg_line,5);
  381.  
  382.       ljstring(QMsgHead->Msgto,strupr(amsg.to),25);
  383.       ljstring(QMsgHead->Msgfrom,strupr(amsg.from),25);
  384.       ljstring(QMsgHead->Msgsubj,amsg.subj,25);
  385.       sprintf(msg_line,"%d",amsg.reply);
  386.       ljstring(QMsgHead->Msgrply,msg_line,8);
  387.  
  388.       QMsgHead->Msgarealo = (char) (msgupd->areano % 255); /* Lo byte area # */
  389.       QMsgHead->Msgareahi = (char) (msgupd->areano / 255); /* Hi byte area # */
  390.  
  391.       filepos = ftell(MsgFile);        /* save position for later */
  392.       fwrite(QMsgHead,128,1,MsgFile);        /* Write out the header */
  393.  
  394. /* Ok, now the tough part. We have to plunge thru the message buffer
  395.    strip hidden lines, translate cr's to 0xe3, write out
  396.    messge text in 128 byte record chunks. */
  397.  
  398.        j=0;
  399.        start=0;
  400.       while (msgbuffer[j] == '\0') {
  401.          j++;
  402.          start++;
  403.       }
  404.  
  405.       n = 0;
  406.       origin = FALSE;
  407.       newline = TRUE;
  408.       for (j = start; j < (int) size; j++) {
  409.          switch ((byte) msgbuffer[j]) {
  410.             case 1:        /* Hidden line */
  411.                while (msgbuffer[j] != 0x0d && msgbuffer[j] != 0x8d)     /* Skip special lines */
  412.                   j++;
  413.                newline = FALSE;
  414.                break;
  415.  
  416.             case 'S':        /* Maybe a seenby? */
  417.                if (newline) {
  418.                   _fstrncpy((char _far *)temp1,msgbuffer+j,8);
  419.                   temp1[8] = 0;
  420.                   if (strcmpi(temp1,"SEEN-BY:") == 0) {
  421.                      while (msgbuffer[j] != 0x0d)        /* Skip special lines */
  422.                         j++;
  423.                   }
  424.                   else msg_line[n++] = msgbuffer[j];
  425.                   newline = FALSE;
  426.                }
  427.                else msg_line[n++] = msgbuffer[j];
  428.                break;
  429.  
  430.             case ' ':        /* Maybe an origin line? */
  431.                if (newline) {
  432.                   _fstrncpy((char _far *)temp1,msgbuffer+j,10);
  433.                   temp1[10] = 0;
  434.                   if (strcmpi(temp1," * Origin:") == 0) {
  435.                      msg_line[n++] = msgbuffer[j];
  436.                      origin = TRUE;
  437.                   }
  438.                   else msg_line[n++] = msgbuffer[j];
  439.                   newline = FALSE;
  440.                }
  441.                else msg_line[n++] = msgbuffer[j];
  442.                break;
  443.  
  444.             case 'P':
  445.                if (newline) {
  446.                   _fstrncpy((char _far *)temp1,msgbuffer+j,4);
  447.                   temp1[4] = 0;
  448.                   if (strcmpi(temp1,"PATH") == 0) {
  449.                      while (msgbuffer[j] != 0x0d)        /* Skip special lines */
  450.                         j++;
  451.                   }
  452.                   else msg_line[n++] = msgbuffer[j];
  453.                   newline = FALSE;
  454.                }
  455.                else msg_line[n++] = msgbuffer[j];
  456.                break;
  457.  
  458.             case 0x8d:        /* Soft c/r */
  459.             case 0x0d:        /* Standard c/r */
  460.                msg_line[n] = 0xe3;
  461.                n++;
  462.                newline = TRUE;
  463.                if (origin) /* Eliminate further copying after origin line */
  464.                   j = (int) size;
  465.                break;
  466.  
  467.             case 0x0a:        /* Skip linefeeds */
  468.                newline = TRUE;
  469.                break;
  470.  
  471.             case 0:
  472.             case 0x80:
  473.                newline = FALSE;
  474.                break;
  475.  
  476.             default:
  477.                newline = FALSE;
  478.                msg_line[n++] = msgbuffer[j];
  479.                break;
  480.          }
  481.          if (n >= 128) {
  482.             msg_line[128] = 0;
  483.             fwrite(msg_line,128,1,MsgFile);     /* Write out a record */
  484.             n = 0;
  485.             TotRecs++;
  486.             recs++;
  487.             memset(msg_line,' ',128);
  488.          }
  489.       }
  490.       if (n) {        /* Partial record */
  491.          recs++;
  492.          msg_line[128] = 0;
  493.          fwrite(msg_line,128,1,MsgFile);     /* Write out a record */
  494.          TotRecs++;
  495.       }
  496.  
  497. /* Now update with record count */
  498.       fseek(MsgFile,filepos,SEEK_SET);        /* Restore back to header start */
  499.       sprintf(msg_line,"%d",recs);
  500.       ljstring(QMsgHead->Msgrecs,msg_line,6);
  501.       fwrite(QMsgHead,128,1,MsgFile);        /* Write out the header */
  502.       fseek(MsgFile,0L,SEEK_END);        /* Bump back to end of file */
  503.    }
  504.    return(i);        /* No errors!, return message number */
  505. }
  506.  
  507. /* QWK handling cleanup */
  508. void _pascal closeqwk(void)
  509. {
  510.    if (Indx != -1) {
  511.       close(Indx);
  512.       Indx = -1;
  513.    }
  514.  
  515.    if (PIndx != -1) {
  516.       close(PIndx);
  517.       PIndx = -1;
  518.    }
  519.  
  520.    if (MsgFile != NULL) {
  521.       fclose(MsgFile);
  522.       MsgFile = NULL;
  523.    }
  524. }
  525.  
  526. /* Convert an IEEE floating point number to MSBIN
  527.    floating point decimal */
  528.  
  529. float _pascal IEEToMSBIN(float f)
  530. {
  531.    union Converter t;
  532.    int   sign,exp;
  533.  
  534.    t.f[0] = f;
  535.  
  536. /* Extract sign & change exponent bias from 0x7f to 0x81 */
  537.  
  538.    sign = t.uc[3] / 0x80;
  539.    exp  = ((t.ui[1] >> 7) - 0x7f + 0x81) & 0xff;
  540.  
  541. /* reassemble them in MSBIN format */
  542.    t.ui[1] = (t.ui[1] & 0x7f) | (sign << 7) | (exp << 8);
  543.    return t.f[0];
  544. }
  545.  
  546.  
  547. /* Fetch REP packet from user and import if ok */
  548. void _pascal getrep(void)
  549. {
  550.    int x,y,z,msgfile,RDONLY;
  551.    int endspace;
  552.    char  *msgbuff,*p;
  553.    struct dostime_t time;
  554.    struct dosdate_t date;
  555.    struct QWKmsghd *MsgHead;
  556.    struct msgupd_st *msgupd;
  557.    FILE   *tosslog;
  558.  
  559.    if (repupload() > 0) {        /* We have received a REP packet perhaps */
  560.       Aindex = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  561.       if (Aindex == -1)
  562.          aborterror(FILEOPEN,"Error opening Area index file");
  563.       tempdir();
  564.       sprintf(temp,"%s.rep",BBSid);
  565.       if(!extractarc(temp)) {        /* Parse the bbs.msg file and import */
  566.          upmsgs = 0;
  567.          confreqs = 0;
  568.          sprintf(temp,"%s.msg",BBSid);
  569.          repfile = sopen(temp,O_BINARY | O_RDONLY,SH_DENYRW,S_IREAD);
  570.          if (repfile >= 0) {
  571.             MsgHead = (struct QWKmsghd *) malloc(sizeof(struct QWKmsghd));
  572.             if (MsgHead == NULL)
  573.                aborterror(BADALLOC,NULL);
  574.             msgbuff = (char *) malloc(150);
  575.             if (msgbuff == NULL)
  576.                aborterror(BADALLOC,NULL);
  577.             read(repfile,msgbuff,128);        /* Ignore first record */
  578.             msgbuff[8] = 0;
  579.             stripwhite(msgbuff);
  580.             RP1 = NULL;
  581.             if (strcmpi(BBSid,msgbuff) == 0) {        /* Make sure it's ours! */
  582.                setcolor(TextAttr[STD_TEXT]);
  583.                strout("\r\nHang on while I import the messages.\r\n\r\n");
  584.                setcolor(TextAttr[HILITE_TEXT]);
  585.                x = read(repfile,(struct QWKmsghd *) MsgHead,128);
  586.                while (x == 128) {        /* This is the BBS.MSG import loop */
  587.          /* Build the Fidonet message head */
  588.                   x = atoi(MsgHead->Msgnum);        /* Area number */
  589.                   rp = RP1;
  590.                   RPprev = RP1;
  591.                   while (rp != NULL) {        /* Search for same area */
  592.                      if (rp->areano == x)
  593.                         break;
  594.                      else {
  595.                         RPprev = rp;
  596.                         rp = rp->next;
  597.                      }
  598.                   }
  599.                   if (rp == NULL) {        /* New message area */
  600.                      rp = (struct repmsg _far *) _fmalloc(sizeof(struct repmsg));
  601.                      if (rp == NULL)
  602.                         aborterror(BADALLOC,NULL);
  603.                      rp->count = 0;
  604.                      rp->next = NULL;
  605.                      rp->areano = x;
  606.                      rp->flags = 0;
  607.                      if (RP1 == NULL) {        /* First one */
  608.                         RP1 = rp;
  609.                      }
  610.                      else RPprev->next = rp;        /* Link it in */
  611.                   }
  612.                   msgupd = MSGUPD_1;
  613.                   while (msgupd != NULL) {        /* Is it selected area? */
  614.                      if (msgupd->areano == (word) x)
  615.                         break;
  616.                      else msgupd = msgupd->next;
  617.                   }
  618.                   if (msgupd == NULL) { /* Not user selected area, create a fake one */
  619.                      msgupd = (struct msgupd_st *) malloc(sizeof(struct msgupd_st));
  620.                      if (msgupd != NULL) {
  621.                         msgupd->areano = x;
  622.                         if ((lseek(Aindex,(long) (x * sizeof(struct _aidx)),SEEK_SET)) != -1L) {
  623.                            if((read(Aindex,(char *)&IDX,sizeof(struct _aidx))) == sizeof(struct _aidx)) {
  624.                               fseek(afile,IDX.offset,SEEK_SET);
  625.                               fread(&AREA,astrlen,1,afile);
  626.                               msgupd->attribute = (word) AREA.attrib[UserClass];
  627.                               msgupd->next = NULL;
  628.                               if (AREA.msgpath[0] && (AREA.areano == IDX.area)) {
  629.                                  strcpy(msgupd->msgpath,AREA.msgpath);
  630.                                  msgupd->update = -2;        /* Flag that its fake */
  631.                                  msgupd->readmsgs = 0;        /* # of replies */
  632.                               }
  633.                               else {
  634.                                  free(msgupd);
  635.                                  msgupd = NULL;
  636.                               }
  637.                            }
  638.                            else {
  639.                               free(msgupd);
  640.                               msgupd = NULL;
  641.                            }
  642.                         }
  643.                         else {
  644.                            free(msgupd);
  645.                            msgupd = NULL;
  646.                         }
  647.                      }
  648.                   }
  649.                   upmsgs++;
  650.                   sprintf(temp,"Importing message # %d\r",upmsgs);
  651.                   strout(temp);
  652.                   if ((msgupd->attribute & NOPUBLIC) && (msgupd->attribute & NOPRIVATE)
  653.                      && LastUser.priv < ASSTSYSOP)
  654.                         RDONLY = TRUE;
  655.                   else RDONLY = FALSE;
  656.                   if (msgupd != NULL && !RDONLY) { /* Create the fidonet message */
  657.                      msgrecs = atoi(MsgHead->Msgrecs) - 1;
  658.                   /* Parse date and time junk */
  659.                      strncpy(temp,MsgHead->Msgdate,8);
  660.                      temp[8] = 0;
  661.                      p = strtok(temp,"-");        /* Fetch month */
  662.                      x = amsg.date_written.date.mo = atoi(p);
  663.                      p = strtok(NULL,"-");        /* Fetch day */
  664.                      z = amsg.date_written.date.da = atoi(p);
  665.                      p = strtok(NULL," \0-");        /* Fetch year */
  666.                      y = amsg.date_written.date.yr = (atoi(p) - 80);
  667.  
  668.                      strncpy(temp,MsgHead->Msgtime,5);
  669.                      temp[5] = 0;
  670.                      sprintf(amsg.date,"%d %s %d %s:00",z,monthstr[x-1],y+80,temp);
  671.  
  672.                      p = strtok(temp,":");        /* Fetch hour */
  673.                      amsg.date_written.time.hh = atoi(p);
  674.                      p = strtok(NULL,"\0:");        /* Fetch minutes */
  675.                      amsg.date_written.time.mm = atoi(p);
  676.                      amsg.date_written.time.ss = 0; /* Clear seconds */
  677.  
  678.                      _dos_getdate(&date);
  679.                      _dos_gettime(&time);
  680.  
  681.                      amsg.date_arrived.date.mo = date.month;
  682.                      amsg.date_arrived.date.da = date.day;
  683.                      amsg.date_arrived.date.yr = date.year - 1980;
  684.                      amsg.date_arrived.time.hh = time.hour;
  685.                      amsg.date_arrived.time.mm = time.minute;
  686.                      amsg.date_arrived.time.ss = time.hsecond;
  687.                      amsg.attr = 0;
  688.                      if (MsgHead->Msgstat == '*') {
  689.                         if (!(msgupd->attribute & NOPRIVATE))
  690.                            amsg.attr |= MSGPRIVATE;
  691.                      }
  692.                      amsg.orig = prm.address[0].Node;     /* Original node number */
  693.                      amsg.orig_net = prm.address[0].Net; /* Original net number */
  694.                      amsg.dest = prm.address[0].Node;     /* Original node number */
  695.                      amsg.dest_net = prm.address[0].Net; /* Original net number */
  696.                      amsg.reply = atoi(MsgHead->Msgrply);
  697.                      amsg.times = 1;
  698.                      amsg.up = 0;
  699.                      amsg.cost = 0;
  700.    
  701.                      memset(amsg.from,0,36);
  702.                      memset(amsg.to,0,36);
  703.                      memset(amsg.subj,0,72);
  704.                      strcpy(amsg.to,namefixup(MsgHead->Msgto));
  705.                      strcpy(amsg.from,namefixup(MsgHead->Msgfrom));
  706.                      strcpy(amsg.subj,namefixup(MsgHead->Msgsubj));
  707.  
  708.                      if(!qwkfunct(msgupd,msgbuff)) {        /* A genuine message */
  709.                      /* Ok write out the fidonet header */
  710.                         lseek(Aindex,(long) (msgupd->areano * sizeof(struct _aidx)),SEEK_SET);
  711.                         read(Aindex,(char *)&IDX,sizeof(struct _aidx));
  712.                         fseek(afile,IDX.offset,SEEK_SET);
  713.                         fread(&AREA,astrlen,1,afile);
  714.                         switch (AREA.area_type) {
  715.                            case 0:        /* Fido 1.msg style */
  716.                               msgupd->himsg = find_fidohigh(AREA.msgpath);
  717.                               break;
  718.  
  719.                            default:
  720.                               msgupd->himsg = find_fidohigh(AREA.msgpath);
  721.                               break;
  722.                         }
  723.                         if (msgupd->himsg == 0xffff )
  724.                            msgupd->himsg = 0;
  725.                         msgupd->startmsg = get_lastread(msgupd->msgpath);
  726.                         sprintf(temp1,"%s%d.msg",msgupd->msgpath,msgupd->himsg+1);
  727.                         msgfile = sopen(temp1,O_TRUNC | O_CREAT | O_BINARY | O_RDWR,SH_DENYRW,S_IWRITE);
  728.                         y = sizeof(struct _msg);
  729.                         write(msgfile,(char *) &amsg,y);
  730.                         rp->count += 1;
  731.  
  732.                   /* Now prepare to read in the REP msg and convert to fidonet */
  733.                         for (x=0; x < msgrecs; x++) {
  734.                            read(repfile,msgbuff,128);
  735.                            msgbuff[128] = 0;
  736.                            p = strchr(msgbuff,0xe3);        /* Look for special linefeeds */
  737.                            while (p) {
  738.                               *p = 0x0d;        /* Replace as a cr */
  739.                               p = strchr(p+1,0xe3);
  740.                            }
  741.                            p = msgbuff + 127;
  742.                            endspace = TRUE;
  743.                   /* Now go backwards and strip out '---' after a c/r */
  744.                            while (p > msgbuff) {
  745.                               if (*p == '-' && StripTags && (msgupd->attribute & ECHOMAIL)) {
  746.                                  endspace = FALSE;
  747.                                  p--;
  748.                                  if (*p == '-') {
  749.                                     p--;
  750.                                     if (*p == '-') {
  751.                                        if (*(p-1) == '\r') {
  752.                                           *p = ' ';
  753.                                           *(p+1) = ' ';
  754.                                           *(p+2) = ' ';
  755.                                        }
  756.                                        break;
  757.                                     }
  758.                                  }
  759.                               }
  760.                               if (*p & 0x80) {    /* Hi bit set? */
  761.                                  if(!(msgupd->attribute & HIGHBIT))
  762.                                     *p &= 0x7f;        /* Make it harmless */
  763.                                  endspace = FALSE;
  764.                               }
  765.                               if ((x == (msgrecs - 1)) && *p == ' ' && endspace && *(p-1) == ' ') 
  766.                                  *p = 0;
  767.                               else endspace = FALSE;
  768.                               p--;
  769.                            }
  770.                            y = strlen(msgbuff);
  771.                            write(msgfile,msgbuff,y);
  772.                         }
  773.                         strcpy(msgbuff,"\r\n");
  774.                         write(msgfile,msgbuff,3);
  775.                         close(msgfile);
  776.                         msgupd->startmsg++;
  777.                         msgupd->himsg++;
  778.                         adjust_lastread(msgupd->msgpath,msgupd->himsg);
  779.                         if (msgupd->update == -2)     /* A fake one? */
  780.                            free(msgupd);
  781.                      }
  782.                   }
  783.                   else {        /* Invalid message, skip to next one */
  784.                      msgrecs = atoi(MsgHead->Msgrecs) - 1;
  785.                      for (x=0; x < msgrecs; x++) 
  786.                         read(repfile,msgbuff,128);
  787.                   }
  788.                   x = read(repfile,(struct QWKmsghd *) MsgHead,128);
  789.                }
  790.                free(MsgHead);
  791.                free(msgbuff);
  792.                close(repfile);
  793.             }
  794.             else {
  795.                setcolor(TextAttr[ATTN_TEXT]);
  796.                strout("\r\nSorry, but this REP packet is not addressed to us!\r\n\r\n");
  797.                logit("REP packet upload has invalid BBS id",'!');
  798.             }
  799.          }
  800.          else {
  801.             setcolor(TextAttr[ATTN_TEXT]);
  802.             strout("\r\nSorry but the REP pack can not be opened.\r\n");
  803.             logit("REP open file error",'!');
  804.          }
  805.       }
  806.       else {
  807.          setcolor(TextAttr[ATTN_TEXT]);
  808.          strout("\r\nSorry but the REP pack can not be extracted.\r\n");
  809.          logit("REP packet extraction error",'!');
  810.       }
  811.    /* Cleanup */
  812.       sprintf(temp,"%s.rep",BBSid);
  813.       unlink(temp);
  814.       sprintf(temp,"%s.msg",BBSid);
  815.       unlink(temp);
  816.       homedir();
  817.       if (upmsgs) {
  818.          Exitcode = 6;
  819.          HaveUpl = TRUE;
  820.          sprintf(temp,"Total of %d messages were uploaded",upmsgs);
  821.          setcolor(TextAttr[MENU_KEY]);
  822.          strout("\r\n");
  823.          strout(temp);
  824.          strout("\r\n");
  825.          logit(temp,'#');
  826.          setcolor(TextAttr[HILITE_TEXT]);
  827.          rp = RP1;
  828.          tosslog = NULL;
  829.          while (rp) {
  830.             if (rp->count) {        /* A valid import message */
  831.                lseek(Aindex,(long) (rp->areano * sizeof(struct _aidx)),SEEK_SET);
  832.                read(Aindex,(char *)&IDX,sizeof(struct _aidx)); 
  833.                fseek(afile,IDX.offset,SEEK_SET);
  834.                fread(&AREA,astrlen,1,afile);
  835.                strncpy(temp1,AREA.msginfo,25);
  836.                temp1[25] = 0;
  837.                stripwhite(temp1);
  838.                sprintf(temp,"Importing %d messages into [%s]",rp->count,temp1);
  839.                strout(temp);
  840.                strout("\r\n");
  841.                logit(temp,'#');
  842.                if (tosslog == NULL && (AREA.attrib[UserClass] & ECHOMAIL)
  843.                   && AREA.msgname[0])
  844.                      tosslog = _fsopen(PRM(echotoss_name),"at+",SH_DENYNO);
  845.                if (tosslog != NULL && (AREA.attrib[UserClass] & ECHOMAIL)
  846.                   && AREA.msgname[0]) {
  847.                   sprintf(temp,"%s\n",AREA.msgname);
  848.                   fputs(temp,tosslog);
  849.                }
  850.             }
  851.             else {
  852.                if (rp->flags == 0) 
  853.                   sprintf(temp,"Messages to area # %d were ignored",rp->areano);
  854.                else sprintf(temp,"Messages to area # %d were MaxMail commands",rp->areano);
  855.                strout(temp);
  856.                strout("\r\n");
  857.                logit(temp,'#');
  858.             }
  859.             RPprev = rp;
  860.             rp = rp->next;
  861.             _ffree(RPprev);
  862.          }
  863.          if (tosslog != NULL)
  864.             fclose(tosslog);
  865.       }
  866.       setcolor(TextAttr[HILITE_TEXT]);
  867.       strout("\r\n");
  868.       if (confreqs) {
  869.          sprintf(temp,"User made %d requests for area changes",confreqs);
  870.          strout(temp);
  871.          strout("\r\n");
  872.          logit(temp,'#');
  873.       }
  874.       close(Aindex);
  875.    }
  876. }
  877.  
  878. /* Test and process special door functions from QWK messages.
  879.    return FALSE if none */
  880. int _pascal qwkfunct(struct msgupd_st *msgupd,char *msgbuff)
  881. {
  882.    char *p;
  883.  
  884.    if ((strcmpi(amsg.to,"QMAIL") == 0)  ||        /* Default */
  885.          (strcmpi(amsg.to,"MAXMAIL") == 0)) {        /* Uh oh, its for us! */
  886.       rp->flags |=  RP_CMDFLAG;
  887.       if (strcmpi(amsg.subj,"CONFIG") == 0) {        /* Sometimes its this one */
  888.          read(repfile,msgbuff,128);
  889.          msgbuff[128] = 0;
  890.          stripwhite(msgbuff);
  891.          p = strtok(msgbuff," \n\r");
  892.          if (strcmpi(p,"ADD") == 0) {        /* Add this conference */
  893.             if(!isskiparea(msgupd->areano)) {
  894.                if(is_selarea(msgupd->areano)) {
  895.                   sprintf(temp,"You already have Conference #%03d enabled\r\n",msgupd->areano);
  896.                   setcolor(TextAttr[ATTN_TEXT]);
  897.                   strout(temp);
  898.                }
  899.                else {
  900.                   sprintf(temp,"Adding conference #%03d",msgupd->areano);
  901.                   strout(temp);
  902.                   logit(temp,'#');
  903.                   strout("\r\n");
  904.                   msgmark(msgupd->areano);
  905.                   confreqs++;
  906.                   upmsgs--;
  907.                }
  908.             }
  909.          }
  910.          else if (strcmpi(p,"DROP") == 0) {        /* Remove this conference */
  911.             if(!isForcearea(msgupd->areano)) {
  912.                if (!is_selarea(msgupd->areano)) {
  913.                   sprintf(temp,"Conference #%03d was not enabled\r\n",msgupd->areano);
  914.                   setcolor(TextAttr[ATTN_TEXT]);
  915.                   strout(temp);
  916.                }
  917.                else {
  918.                   sprintf(temp,"Dropping conference #%03d",msgupd->areano);
  919.                   strout(temp);
  920.                   logit(temp,'#');
  921.                   strout("\r\n");
  922.                   confreqs++;
  923.                   msgunmark(msgupd->areano);
  924.                   upmsgs--;
  925.                }
  926.             }
  927.          }
  928.       }
  929.       else if (strcmpi(amsg.subj,"DROP") == 0) {        /* But usually this way */
  930.          read(repfile,msgbuff,128);        /* Drop a conference */
  931.          if(!isForcearea(msgupd->areano)) {
  932.             if(!is_selarea(msgupd->areano)) {
  933.                sprintf(temp,"Conference #%03d was not enabled\r\n",msgupd->areano);
  934.                setcolor(TextAttr[ATTN_TEXT]);
  935.                strout(temp);
  936.             }
  937.             else {
  938.                sprintf(temp,"Dropping conference #%03d",msgupd->areano);
  939.                strout(temp);
  940.                logit(temp,'#');
  941.                strout("\r\n");
  942.                confreqs++;
  943.                msgunmark(msgupd->areano);
  944.                upmsgs--;
  945.             }
  946.          }
  947.       }
  948.       else if (strcmpi(amsg.subj,"ADD") == 0) {
  949.          read(repfile,msgbuff,128);        /* Add a conference */
  950.          if(!isskiparea(msgupd->areano)) {
  951.             if(is_selarea(msgupd->areano)) {
  952.                sprintf(temp,"You already have Conference #%03d enabled\r\n",msgupd->areano);
  953.                setcolor(TextAttr[ATTN_TEXT]);
  954.                strout(temp);
  955.             }
  956.             else {
  957.                sprintf(temp,"Adding conference #%03d",msgupd->areano);
  958.                strout(temp);
  959.                logit(temp,'#');
  960.                strout("\r\n");
  961.                msgmark(msgupd->areano);
  962.                confreqs++;
  963.                upmsgs--;
  964.             }
  965.          }
  966.       }
  967.       return TRUE;
  968.    }
  969.    else return FALSE;
  970. }
  971.  
  972. char * _pascal namefixup(char *name)
  973. {
  974.    int x,y;
  975.    static char tname[81];
  976.  
  977.    strncpy(tname,name,80);
  978.    tname[20] = 0;
  979.    stripwhite(tname);
  980.    strlwr(tname);
  981.  
  982.    tname[0] = (char) toupper((int) tname[0]);
  983.    y = (int) strlen(tname);
  984.  
  985.    for (x = 0; x < y; x++) {
  986.       if (isspace(tname[x])) {
  987.          x++;
  988.          tname[x] = (char) toupper((int) tname[x]);
  989.       }
  990.    }
  991.    return (&tname[0]);
  992. }
  993.  
  994.